package com.ruoyi.system.pay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeQueryModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.pay.config.AlipayConfig;
import com.ruoyi.system.pay.domain.dto.OrderQueryDTO;
import com.ruoyi.system.pay.domain.po.PayOrder;
import com.ruoyi.system.pay.domain.dto.PayRequestDTO;
import com.ruoyi.system.pay.domain.vo.PayOrderVO;
import com.ruoyi.system.pay.mapper.PayOrderMapper;
import com.ruoyi.system.pay.service.IPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 支付宝支付实现
 * 事务管理：
 * 防止重复支付
 * 订单状态管理
 * 数据库操作 try-catch 处理异常
 * 回调处理：
 * 校验支付宝的回调签名，确保数据安全。
 */
@Slf4j
@Service
public class AlipayServiceImpl implements IPayService {

    @Autowired
    private AlipayConfig alipayConfig;

    @Autowired
    private PayOrderMapper payOrderMapper;

    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    /**
     * 创建支付宝支付订单
     */
    @Override
    @Transactional
    public String createPayOrder(PayOrder order) {
        // 1. 校验订单是否已存在
        PayOrder existingOrder = payOrderMapper.findByOrderNumber(order.getOrderNumber());
        if (existingOrder != null && "PAID".equals(existingOrder.getStatus())) {
            throw new RuntimeException("该订单已支付");
        }

        // 2. 设置唯一的订单号
        order.setOrderNumber(UUID.randomUUID().toString());

        // 3. 设置订单初始状态为未支付
        order.setStatus("UNPAID");
        order.setUserId(1L);// 测试 后续删除
        order.setAmount(BigDecimal.valueOf(0.01));
        order.setPaymentTime(new Date());
        order.setPayMethod("ALIPAY");
        order.setTransactionId(UUID.randomUUID().toString());

        // 4. 保存订单到数据库
        payOrderMapper.insertOrder(order);

        // 5. 调用支付宝创建支付
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.getGatewayUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getMerchantPrivateKey(),
                "json",
                alipayConfig.getCharset(),
                alipayConfig.getAlipayPublicKey(),
                alipayConfig.getSignType()
        );

        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        request.setReturnUrl(alipayConfig.getReturnUrl());
        request.setNotifyUrl(alipayConfig.getNotifyUrl());

        //// 扩展信息，按需传入
        JSONObject extendParams = new JSONObject();
        extendParams.put("sys_service_provider_id", 1);

        request.setBizContent("{\"out_trade_no\":\"" + order.getOrderNumber() + "\","  // 使用交易流水号
                + "\"total_amount\":\"" + order.getAmount() + "\","
                + "\"subject\":\"支付订单\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        try {
            String body = alipayClient.pageExecute(request).getBody();
            System.out.println(body);
            return body;
        } catch (AlipayApiException e) {
            throw new RuntimeException("支付失败", e);
        }
    }

    /**
     * 验证支付宝支付回调
     *
     * @param request HTTP 请求对象，包含回调参数
     * @return 验证结果，true 表示验证成功
     */
    @Override
    public boolean verifyPayCallback(HttpServletRequest request) {
        try {
            // 1. 获取回调参数并封装到 Map 中
            Map<String, String> params = getAlipayParams(request);

            // 2. 调用支付宝 SDK 进行签名验证
            boolean signVerified = AlipaySignature.rsaCheckV1(
                    params,
                    alipayConfig.getAlipayPublicKey(),
                    alipayConfig.getCharset(),
                    alipayConfig.getSignType()
            );

            if (signVerified) {
                log.info("【支付回调验证成功】, params: {}", params);
                return true;
            } else {
                log.error("【支付回调验证失败】, params: {}", params);
                return false;
            }
        } catch (AlipayApiException e) {
            log.error("【支付回调异常】", e);
            return false;
        }
    }

    /**
     * 解析支付宝回调参数
     *
     * @param request HTTP 请求
     * @return 参数 Map
     */
    private Map<String, String> getAlipayParams(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();

        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            StringBuilder valueStr = new StringBuilder();

            for (int i = 0; i < values.length; i++) {
                valueStr.append(i == values.length - 1 ? values[i] : values[i] + ",");
            }
            params.put(name, valueStr.toString());
        }
        return params;
    }


    /**
     * 查询订单状态
     */
    @Override
    public PayOrder getOrderStatus(String orderNumber) {
        return payOrderMapper.findByOrderNumber(orderNumber);
    }

    @Override
    @Transactional
    public void updateOrderStatus(String orderNumber, String tradeNo, String status) {
        PayOrder order = payOrderMapper.findByOrderNumber(orderNumber);
        if (order != null && !"PAID".equals(order.getStatus())) {
            order.setStatus(status);
            order.setTransactionId(tradeNo);  // 设置支付宝流水号
            order.setPaymentTime(new Date()); // 记录支付时间
            payOrderMapper.updateOrder(order);
            log.info("【订单状态更新】订单号: {}, 状态: {}, 支付宝流水号: {}", orderNumber, status, tradeNo);
        }
    }

    /**
     * 统一支付方法
     */
    @Override
    public String unifiedPay(PayRequestDTO payRequestDTO) {
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.getGatewayUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getMerchantPrivateKey(),
                "json",
                alipayConfig.getCharset(),
                alipayConfig.getAlipayPublicKey(),
                alipayConfig.getSignType()
        );

        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        request.setReturnUrl(alipayConfig.getReturnUrl());
        request.setNotifyUrl(alipayConfig.getNotifyUrl());
        HashMap<String, String> map = new HashMap<>();
        map.put("source_type",payRequestDTO.getSourceType());
//        request.setBizContent("{\"out_trade_no\":\"" + payRequestDTO.getOrderNumber() + "\","
//                + "\"total_amount\":\"" + payRequestDTO.getAmount() + "\","
//                + "\"subject\":\"" + payRequestDTO.getSubject() + "\","
//                + "\"source_type\":\"" + payRequestDTO.getSourceType() + "\","  //商城、医疗、
//                + "\"product_code\":\"QUICK_WAP_WAY\"}");
        request.setBizContent("{\"out_trade_no\":\"" + payRequestDTO.getSourceType()+payRequestDTO.getOrderNumber() + "\","
                + "\"total_amount\":\"" + payRequestDTO.getAmount() + "\","
                + "\"subject\":\"" + payRequestDTO.getSubject() + "\","
                + "\"passback_params\":\"" + map.toString() + "\","
                + "\"product_code\":\"QUICK_WAP_WAY\"}");

        try {
            return alipayClient.pageExecute(request).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
            log.error("支付宝支付失败", e);
            throw new RuntimeException("支付失败", e);
        }
    }

    /**
     * 查询订单
     */
    @Override
    public PayOrderVO queryOrder(OrderQueryDTO queryDTO) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.getGatewayUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getMerchantPrivateKey(),
                "json",
                alipayConfig.getCharset(),
                alipayConfig.getAlipayPublicKey(),
                alipayConfig.getSignType()
        );
        // 构造请求参数以调用接口
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayTradeQueryModel model = new AlipayTradeQueryModel();

        // 设置订单支付时传入的商户订单号
        model.setOutTradeNo(queryDTO.getSourceType()+queryDTO.getOrderNumber());

        // 设置支付宝交易号
//        model.setTradeNo("2014112611001004680 073956707");
        // 设置查询选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("trade_settle_info");
        model.setQueryOptions(queryOptions);
        request.setBizModel(model);

        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());
        Map map = JSONObject.parseObject(response.getBody(), Map.class);

        //获取内层的json数据
        Object o = map.get("alipay_trade_query_response");
        Map mapData = JSONObject.parseObject(o+"", Map.class);
        System.out.println(map.get("ext_infos"));
        System.out.println("passback_params"+map.get("passback_params"));
//        System.out.println(mapData.get("sub_msg"));
        //获取交易状态
        Object resStatus = mapData.get("trade_status");
        if (resStatus == null){
            return null;
        }
        PayOrderVO result = new PayOrderVO();
        String orderNumber = mapData.get("out_trade_no").toString();

        result.setOrderNumber(orderNumber);
        result.setAmount(mapData.get("total_amount").toString());
        result.setStatus("trade_status");
        Date date = null;
        try {
            date = format.parse(mapData.get("send_pay_date").toString());
            System.out.println("转换后的 Date 对象: " + date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        result.setPaymentTime(date);
        result.setTransactionId(mapData.get("trade_no").toString());

//        result.setSourceType();
        return result;
//        PayOrder payOrder = payOrderMapper.findByOrderNumber(queryDTO.getOrderNumber());
//        if (payOrder == null) {
//            throw new RuntimeException("订单不存在！");
//        }
//        PayOrderVO payOrderVO = new PayOrderVO();
//        payOrderVO.setOrderNumber(payOrder.getOrderNumber());
//        payOrderVO.setAmount(payOrder.getAmount());
//        payOrderVO.setStatus(payOrder.getStatus());
//        payOrderVO.setPaymentTime(payOrder.getPaymentTime());
//        payOrderVO.setTransactionId(payOrder.getTransactionId());
//        payOrderVO.setSourceType(queryDTO.getSourceType());
//        return payOrderVO;
    }
}
